#ifndef svl_TWindow_H
#define svl_TWindow_H


#pragma warning( disable : 4355 )

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
namespace svl {

///////////////////////////////////////////////////////////////////////////////

struct TWindow
{    
  struct TMessage
  {
    UINT Msg; WPARAM WParam; LPARAM LParam;
    
    TMessage() : Msg(0),WParam(0),LParam(0)           { }
    TMessage(UINT Msg_,WPARAM WParam_,LPARAM LParam_) { Msg = Msg_; WParam = WParam_; LParam = LParam_;}
    
    WORD LParamLo() { return LOWORD(LParam);}
    WORD LParamHi() { return HIWORD(LParam);}
  };
  //
  TWindow();
 ~TWindow();
  //
  operator ::HWND() { return hWnd;}
  //
  void SetParent(HWND     Parent);
  void SetParent(TWindow &Parent) { SetParent(Parent.Handle()); }
  //
  void SetWindowText(char *Text) { ::SetWindowText(hWnd,Text);}
  //
  int MessagesLoop();
  //
  HWND Handle()    { return hWnd;}
  bool IsModal()   { return isModal;}
  bool IsVisible() { return ::IsWindowVisible(hWnd) != 0;}
  //
  virtual void ShowModal();
  void EndModal() { isModal = false;}
  virtual void Show();
  virtual void Hide();
  //
  void MoveWindow(int L,int T,int W,int H,bool Repaint = false) { ::MoveWindow(hWnd,L,T,W,H,Repaint); }
  void UpdateWindow() { ::UpdateWindow(hWnd);}
  //
  void Close()     { ::CloseWindow(hWnd);}
  void SetFocus()  { ::SetFocus(hWnd);}
  bool IsFocused() { return ::GetFocus() == hWnd;}

  void SetCapture()     { ::SetCapture(hWnd);}
  void ReleaseCapture() { if (IsCapture()) { ::ReleaseCapture();} }
  bool IsCapture()      { return hWnd == ::GetCapture();}
  //
  void SetActive() { ::SetActiveWindow(hWnd);}
  bool IsActive()  { return hWnd == ::GetActiveWindow();}

protected:
  virtual LRESULT TWindow_WndProc(TMessage &Message);

private:
  static LRESULT CALLBACK WndProc       (HWND HWnd,UINT Msg,WPARAM WParam,LPARAM LParam);
  static BOOL    CALLBACK EnableWindows (HWND HWnd,LPARAM LParam);
  static BOOL    CALLBACK DisableWindows(HWND HWnd,LPARAM LParam);
  //
  static char className[100];
  static ::WNDCLASS wndClass;
  static bool isFirst;
  ::HWND hWnd;
  bool isMain,isModal;
};

///////////////////////////////////////////////////////////////////////////////

struct TControlEdit
{
  TControlEdit(TWindow &Parent);
 ~TControlEdit();
  //
  operator ::HWND() { return hWnd;}
  HWND GetHandle()         { return hWnd;}
  void SetText(char *V) { ::SetWindowText(hWnd,V);}
  void SetFocus()       { ::SetFocus(hWnd);}
  //
  int  GetTextLength() { return ::SendMessage(hWnd,WM_GETTEXTLENGTH,0,0);}
  void GetText(char *Text,int Size) { ::GetWindowText(hWnd,Text,Size);}
  //
  void MoveWindow(int L,int T,int W,int H,bool Repaint = false) { ::MoveWindow(hWnd,L,T,W,H,Repaint);}
  
protected:
  virtual LRESULT TControl_WndProc(TWindow::TMessage &Message);
  
private:
  static LRESULT CALLBACK WndProc(HWND HWnd,UINT Msg,WPARAM WParam,LPARAM LParam);
  //
  ::HWND hWnd;
  ::HFONT hFont;
  char sFont[20];
  static ::WNDPROC oldWndProc;
};

///////////////////////////////////////////////////////////////////////////////
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
namespace svl { namespace test {

struct TWindowInfoTest : public svl::TWindow
{    
  svl::TControlEdit Edit;
  //
  TWindowInfoTest() : Edit(*this) { Edit.SetText("qwerty");}

protected:
  virtual LRESULT TWindow_WndProc(TMessage &Message);
};

struct TWindow1 : public svl::TWindow
{    
  TWindowInfoTest WindowInfo;

protected:
  virtual LRESULT TWindow_WndProc(TMessage &Message);
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void TestTWindow();
void TestTPopupMenu();

}}
#endif